﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;

namespace Multiprocessing.Core.Units
{
    public abstract class BaseProcessingUnit : IProcessingUnit
    {
        #region Fields

        private bool _disposed;
        private Action _action;

        #endregion

        #region Properties

        public virtual Action Action
        {
            get { return _action; }
            set
            {
                if (IsRunning)
                {
                    throw new ProcessingUnitBlockedException();
                }
                ArgumentValidator.NullValidate(value, "action");
                _action = value;
            }
        }

        public abstract bool IsRunning { get; }

        #endregion

        #region Events

        public event EventHandler Finished;

        #endregion

        #region Methods

        public abstract void Start();

        public abstract void ForceStop();

        public abstract void Wait();
        
        protected virtual void OnFinished()
        {
            EventHandler handler = Volatile.Read(ref Finished);
            if (!ReferenceEquals(handler, null))
            {
                handler(this, EventArgs.Empty);
            }
        }

        protected virtual void Dispose(bool disposing)
        {
            if (!_disposed)
            {
                if (disposing)
                {
                    // dispose resources here
                }
                _disposed = true;
            }
        }

        ~BaseProcessingUnit()
        {
            Dispose(false);
        }

        public void Dispose()
        {
            Dispose(true);
            GC.SuppressFinalize(this);
        }

        #endregion

        
    }
}
